package cn.thoughtworks.school.programCenter.util.excel;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.*;
import java.util.stream.Collectors;

public class AssignmentStatusExcel extends Excel {

    public static Excel init(List<Map<String, String>> data) {
        Excel excel = new AssignmentStatusExcel();
        excel.data = data;
        excel.workbook = new HSSFWorkbook();
        return excel;
    }

    @Override
    public HSSFWorkbook fillData() {
        createFirstSheet();
        createRestsSheet();
        return workbook;
    }

    private void createRestsSheet() {
        Map<String, List<Map<String, String>>> topicsAssignmentStatus = data.stream().collect(Collectors.groupingBy(studentStatus -> studentStatus.get("主题")));
        List<String> topicNames = new ArrayList<>(topicsAssignmentStatus.keySet());
        topicNames.forEach(topicName -> {
            HSSFSheet sheet = workbook.createSheet(topicName);
            List<Map<String, String>> assignmentStatusTitle = getRestsSheetColumnsTitle(topicsAssignmentStatus.get(topicName));
            fillRestsColumnsTitle(sheet, assignmentStatusTitle);
            fillRestsBody(sheet, topicsAssignmentStatus.get(topicName), assignmentStatusTitle);

        });

    }

    private void fillRestsBody(HSSFSheet sheet, List<Map<String, String>> topicAssignmentStatus, List<Map<String, String>> assignmentStatusTitles) {
        Map<String, List<Map<String, String>>> studentsAssignmentStatus = topicAssignmentStatus.stream().collect(Collectors.groupingBy(studentStatus -> studentStatus.get("name")));
        List<String> studentsName = new ArrayList<>(studentsAssignmentStatus.keySet());
        List<String> assignmentTitles = assignmentStatusTitles.stream().map(item -> item.get("作业")).collect(Collectors.toList());
        for (int i = 0; i < studentsName.size(); i++) {
            List<Map<String, String>> currentStudentAssignments = studentsAssignmentStatus.get(studentsName.get(i));
            List<String> studentAssignmentData = new ArrayList<>();
            studentAssignmentData.add(studentsName.get(i));
            studentAssignmentData.add(getFinishProgress(currentStudentAssignments));
            studentAssignmentData.addAll(getRestsStudentAssignmentData(currentStudentAssignments, assignmentTitles));
            HSSFRow row = createRow(sheet, i + 2);

            fillRowData(studentAssignmentData, row);
        }
    }

    private String getFinishProgress(List<Map<String, String>> currentStudentAssignments) {
        long finishedCount = currentStudentAssignments.stream().filter(item -> !(Objects.equals("未提交", item.get("分数"))
            || Objects.equals("已提交", item.get("分数"))))
            .count();

        return currentStudentAssignments.size() + "/" + finishedCount;
    }

    private List<String> getRestsStudentAssignmentData(List<Map<String, String>> studentAssignmentsData, List<String> assignmentTitles) {
        Map<String, List<Map<String, String>>> assignmentMap = studentAssignmentsData.stream().collect(Collectors.groupingBy(studentStatus -> studentStatus.get("作业")));
        return assignmentTitles.stream().map(title -> {
            if (Integer.parseInt(assignmentMap.get(title).get(0).get("已评阅")) > 0) {
                return "已评阅";
            }
            return assignmentMap.get(title).get(0).get("分数");
        }).collect(Collectors.toList());

    }

    private List<Map<String, String>> getRestsSheetColumnsTitle(List<Map<String, String>> studentsAssignmentStatus) {
        return studentsAssignmentStatus.stream()
            .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item -> item.get("作业")))), ArrayList::new));
    }

    private void createFirstSheet() {
        HSSFSheet sheet = workbook.createSheet("训练营学生作业情况");
        List<String> titles = new ArrayList<>();
        titles.add("姓名");
        titles.addAll(getFirstSheetColumnsTitle());
        fillFirstColumnsTitle(sheet, titles);
        fillFirstBody(sheet);
    }

    private List<String> getFirstSheetColumnsTitle() {
        return data.stream()
            .map(studentStatus -> studentStatus.get("主题"))
            .distinct()
            .collect(Collectors.toList());
    }

    protected void fillFirstBody(HSSFSheet sheet) {
        Map<String, List<Map<String, String>>> studentsAssignmentStatus = data.stream()
            .collect(Collectors.groupingBy(item -> item.get("name")));
        List<String> studentsName = new ArrayList<>(studentsAssignmentStatus.keySet());

        for (int i = 0; i < studentsName.size(); i++) {

            List<String> studentAssignmentData = new ArrayList<>();
            studentAssignmentData.add(studentsName.get(i));
            studentAssignmentData.addAll(getFirstStudentAssignmentData(studentsAssignmentStatus.get(studentsName.get(i))));

            HSSFRow row = sheet.createRow(i + 2);
            row.setHeight((short) (25 * 20));

            fillRowData(studentAssignmentData, row);
        }

    }

    private void fillRowData(List<String> data, HSSFRow row) {
        for (int i = 0; i < data.size(); i++) {
            createCell(row, i, data.get(i), getDefaultCellStyle());
        }
    }

    private List<String> getFirstStudentAssignmentData(List<Map<String, String>> studentAssignments) {
        Map<String, List<Map<String, String>>> topics = studentAssignments.stream().collect(Collectors.groupingBy(studentAssignment -> studentAssignment.get("主题")));
        return getFirstSheetColumnsTitle().stream().map(title -> {
            List<Map<String, String>> assignments = topics.get(title);
            return getAssignmentsStatus(assignments);
        }).collect(Collectors.toList());
    }

    private String getAssignmentsStatus(List<Map<String, String>> assignments) {
        return assignments.size() +
            " | " + getCount(assignments, "未提交") +
            "-" + getCount(assignments, "已提交") +
            "-" + getCount(assignments, "未完成") +
            "-" + getCount(assignments, "已完成") +
            "-" + getCount(assignments, "已评阅");

    }

    private long getCount(List<Map<String, String>> assignments, String type) {
        if ("已评阅".equals(type)) {
            return assignments.stream().filter(assignment ->
                Integer.parseInt(assignment.get("已评阅")) > 0).count();
        }
        return assignments.stream().filter(assignment -> assignment.get("分数").equals(type)).count();
    }

    protected void fillFirstColumnsTitle(HSSFSheet sheet, List<String> titles) {
        HSSFRow explainRow = createRow(sheet, 0);
        createMergingCellOrRow(sheet, explainRow, 0, 0, 0, titles.size() - 1, "状态说明（总数|未提交-已提交-未完成-已完成-已评阅）");
        HSSFRow row = createRow(sheet, 1);
        for (int i = 0; i < titles.size(); i++) {
            createCell(row, i, titles.get(i), getDefaultCellStyle());
        }
    }


    protected void fillRestsColumnsTitle(HSSFSheet sheet, List<Map<String, String>> titles) {
        HSSFRow firstTitleRow = createRow(sheet, 0);
        HSSFRow secondTitleRow = createRow(sheet, 1);

        createMergingCellOrRow(sheet, firstTitleRow, 0, 1, 0, 0, "姓名");
        createMergingCellOrRow(sheet, firstTitleRow, 0, 1, 1, 1, "完成进度");
        Map<String, List<Map<String, String>>> topicTitle = titles.stream().collect(Collectors.groupingBy(item -> item.get("任务卡")));

        int firstTitleLastIndex = 0;
        for (int i = 0; i < titles.size(); i++) {
            int index = i + 2;
            if (firstTitleLastIndex < index) {
                if (topicTitle.get(titles.get(i).get("任务卡")).size() <= 1) {
                    createCell(firstTitleRow, index, titles.get(i).get("任务卡"), getDefaultCellStyle());
                    firstTitleLastIndex = index;
                } else {
                    firstTitleLastIndex = index + topicTitle.get(titles.get(i).get("任务卡")).size() - 1;
                    createMergingCellOrRow(sheet, firstTitleRow, 0, 0, index, firstTitleLastIndex, titles.get(i).get("任务卡"));
                }
            }
            createCell(secondTitleRow, index, titles.get(i).get("作业"), getDefaultCellStyle());
        }
    }

    private void createMergingCellOrRow(HSSFSheet sheet, HSSFRow row, int firstRow, int lastRow, int firstColl, int lastCol, String content) {
        HSSFCell cell = row.createCell(firstColl);
        sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstColl, lastCol));
        cell.setCellStyle(getDefaultCellStyle());
        cell.setCellValue(content);
    }
}
